﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.IO.Compression;
using System.Windows.Forms;
using System.Text;

using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace DiskGarden
{
	[Serializable]
	[XmlRoot("root")]
	public class RootNode : CategoryNode
	{
		[field: NonSerialized]
		public event NodeEventHandler NameChanged;
		[field: NonSerialized]
		public event NodeEventHandler NodeMoved;
		[field: NonSerialized]
		public event NodeEventHandler NodeAdded;
		[field: NonSerialized]
		public event NodeEventHandler NodeDeleted;

		public void InvokeNameChanged(Node node)
		{ if (NameChanged != null) NameChanged(node); }

		public void InvokeNodeMoved(Node node)
		{ if (NodeMoved != null) NodeMoved(node); }

		public void InvokeNodeAdded(Node node)
		{ if (NodeAdded != null) NodeAdded(node); }

		public void InvokeNodeDeleted(Node node)
		{ if (NodeDeleted != null) NodeDeleted(node); }

		public RootNode()
		{
			this.type = NodeType.Root;
			base.Root = this;
		}

		// Uaktualnia widok kontrolki TreeView
		public void UpdateTree(TreeView Tree)
		{
			//Node node = Tree.SelectedNode.Tag as Node;
			Tree.BeginUpdate();
			Tree.Nodes.Clear();
			UpdateTree(Tree.Nodes);
			Tree.EndUpdate();
		}

		// Zapisuje drzewo katalogów do skompresowanego pliku XML
		public void SaveToXml(string fileName)
		{
			// otwiera strumień pliku (tworzy plik)
			// podłącza strumień kompresujący pod fsOutput
			// tworzy strumień XMLWritera bazujący na pliku
			FileStream fsOutput = new FileStream(fileName, FileMode.Create);
			GZipStream gzip = new GZipStream(fsOutput, CompressionMode.Compress);
			XmlTextWriter writer = new XmlTextWriter(gzip, Encoding.UTF8);
			// rozpoczyna dokument XML
			// dodaje krótki komentarz
			// tworzy obiekt serializera i podaje mu typ jaki bedzie serializować
			// Serializacja, podaje strumień i obiekt
			// zamkniecie pliku
			writer.WriteStartDocument(true);
			writer.WriteComment("File generated by DiskGarden");
			XmlSerializer xml = new XmlSerializer(typeof(RootNode));
			xml.Serialize(writer, this);
			gzip.Close();
			fsOutput.Close();
		}

		// odczytuje ze skompresowanego pliku XML
		public static RootNode LoadFromXml(string fileName)
		{
			// otwiera plik
			// podłącza strumien dekompresujący
			FileStream fsInput = new FileStream(fileName, FileMode.Open);
			GZipStream gzip = new GZipStream(fsInput, CompressionMode.Decompress);
			XmlSerializer xml = new XmlSerializer(typeof(RootNode));

			RootNode root = (RootNode)xml.Deserialize(gzip);

			root.RebuildParents();
			gzip.Close();
			fsInput.Close();

			return root;
		}

		public void SaveToFile(string fileName)
		{
			FileStream fsOutput = new FileStream(fileName, FileMode.Create);
			GZipStream gzip = new GZipStream(fsOutput, CompressionMode.Compress);
			XmlWriter xml = new XmlTextWriter(gzip, Encoding.UTF8);

			xml.WriteStartDocument();
			xml.WriteStartElement("Root");
			this.WriteXml(xml);
			xml.WriteEndElement();
			xml.WriteEndDocument();
			xml.Close();
			gzip.Close();
			fsOutput.Close();
		}

		public static RootNode LoadFromFile(string fileName)
		{
			FileStream fsInput = new FileStream(fileName, FileMode.Open);
			GZipStream gzip = new GZipStream(fsInput, CompressionMode.Decompress);
			XmlReader xml = new XmlTextReader(gzip);
			xml.MoveToContent();
			RootNode root = new RootNode();
			root.ReadXml(xml);
			root.RebuildParents();
			xml.Close();
			gzip.Close();
			fsInput.Close();
			return root;
		}
		
	}

}
